package com.geek.novel.utils

import android.graphics.Paint
import android.text.TextUtils
import com.geek.novel.ui.ReadView
import kotlin.math.ceil
import kotlin.math.floor

/**
 * 文本的一些工具
 */
class SectionUtil{


	companion object {

		private const val LogTag = "SectionUtil"

		private val charEnterRegex: Regex = Regex("\n+")
		private var paint = Paint()
		
		/**
		 * 将小说标题划分成N行
		 */
		fun divideTitle(title: String?, content: ReadView) : ArrayList<String>{
			val sectionTitle = FormatUtil.isNullToEmpty(title)
			val textSize = content.titleTextSize
			val paint = content.paint
			paint.textSize = textSize
			val w = content.viewWidth - textSize - content.offsetLR
			return this.calcLines(sectionTitle, "", w, paint)
		}

		/**
		 * 将小说章节划分成N页
		 */
		fun divideSection(title: String?, section: String?, content: ReadView) : ArrayList<String>{
			if (section == null || TextUtils.isEmpty(section)) {
				return arrayListOf("")
			}
			val textSize = content.contentTextSize
			val w = content.viewWidth - textSize - content.offsetLR
			val h = content.viewHeight - textSize/2
			val lineSpacingExtra = content.contentLineHeight
			
			paint = content.paint
			
			//计算标题占据的高度
			val titleHeight = calcTitleHeight(title, content)
			
			//可视区高度
			val visibleHeight = h - lineSpacingExtra - content.offsetTB
			
			//计算一个页面可以存在多少行
			val maxLines = floor(visibleHeight.toDouble()/(textSize +lineSpacingExtra)).toInt()
			if(maxLines < 0){
				return arrayListOf("")
			}
			
			//计算第一个页面可以存在多少行
			val firstPageMaxLines = floor((visibleHeight-titleHeight).toDouble()/(textSize +lineSpacingExtra)).toInt()
			
			paint.textSize = textSize
			
			//每个段落之前加两个空格
			val lineSuffix = "　　"
			val lines = this.calcLines(section, lineSuffix, w, paint)
			
			val result = ArrayList<String>()
			
			val curPage = StringBuffer()
			var curLineMax = 0
			for(line in lines){
				curLineMax++
				
				curPage.append(line).append("\n")
				
				//最大行数限制，第一页要加上标题的高度
				val maxLinesLimit = if(result.isEmpty()) firstPageMaxLines else maxLines
				if(curLineMax > maxLinesLimit){
					val curPageString = curPage.toString()
					if(!TextUtils.isEmpty(curPageString.trim())){
						result.add(curPageString)
					}
					curLineMax = 0
					curPage.delete(0, curPage.length)
				}
			}
			val curPageString = curPage.toString()
			if(!TextUtils.isEmpty(curPageString.trim())){
				result.add(curPageString)
			}
			return result
		}
		
		/**
		 * 计算标题高度
		 */
		private fun calcTitleHeight(title: String?, content: ReadView): Float{
			val textSize = content.titleTextSize
			val titleLines = this.divideTitle(title, content)
			var result = (textSize + content.titleTextLineSpace) * titleLines.size
			//加上顶部边距和底部边距
			result += content.titleTextPaddingTop + content.titleTextPaddingBottom
			return result
		}
		
		
		/**
		 * 将文字用汉字隔开，然后读取行
		 */
		private fun calcLines(content: String, lineSuffix: String, w: Float, paint: Paint): ArrayList<String>{
			val result: ArrayList<String> = arrayListOf()
			val curSection = content.replace(charEnterRegex, "\n")
			//计算一行大概能容纳多少个汉字(符号是汉字的一半),然后不够的就继续读文字补全
			val lineLimit: Int = ceil(w.toDouble()/ paint.textSize).toInt()
			
			val lines = curSection.split("\n")
			for (line in lines){
//				LogCatUtil.e("line", line)
				if(TextUtils.isEmpty(line.trim())){
					continue
				}
				val realLine = lineSuffix + line
				//判断是否超过一行，超过一行的话要读取每行容纳的字去计算
				val width = (paint.measureText(realLine)).toInt()
				val num = ceil(width/w.toDouble()).toInt()
				if(num > 1){
					var curLine = realLine
					while (curLine.isNotEmpty()){
						//先读取N个字,计算，多退少补
						var curIndex = lineLimit
						var ss = substring(curLine, 0, curIndex)
						var lineTextLength = paint.measureText(ss)
						while (lineTextLength < w && curIndex<curLine.length){
							val s = substring(curLine, curIndex, curIndex+1)
							lineTextLength += paint.measureText(s)
							ss += s
							curIndex++
						}
						result.add(ss)
//							LogCatUtil.e(LogTag, "${curIndex},${curLine}")
						curLine = if(curIndex < curLine.length-1){
							substring(curLine, curIndex, curLine.length)
						}else{
							""
						}
					}
					
				}else{
					result.add(realLine)
				}
			}
			return result
		}
		
		
		private fun substring(str:String, start:Int, end:Int): String{
			val endIndex = if(end > str.length){
				str.length
			}else{
				end
			}
			return str.substring(start, endIndex)
		}

	}
	
}